﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Mathematics;

namespace System.Windows.Media.DirectShow.Audio
{
    public class AudioPeaks
    {

        private const int NUM_FREQUENCY = 19;
        private int[] METER_FREQUENCY = new int[NUM_FREQUENCY] { 30, 60, 80, 90, 100, 150, 200, 330, 480, 660, 880, 1000, 1500, 2000, 3000, 5000, 8000, 12000, 16000 };

        private WaveFormatExtensible waveFormat;

        public AudioPeaks(WaveFormatExtensible waveFormat)
        {
            this.waveFormat = waveFormat;
        }

        public byte[] GetPeaks(FFTResult[] results)
        {
            byte[] peaks = new byte[NUM_FREQUENCY];

            // Per tutti i canali
            for (int x = 0; x < results.Length; x++)
            {
                byte[] chPeaks = GetPeaksForChannel(results[x]);

                // Unisco i picchi dei due canali: tengo quello più alto
                for (int i = 0; i < NUM_FREQUENCY; i++)
                {
                    peaks[i] = Math.Max(peaks[i], chPeaks[i]);
                }
            }

            return peaks;
        }

        private byte[] GetPeaksForChannel(FFTResult result)
        {
            // waveFormat.BitsPerSample == 8
            double maxAmpl = (32767.0 * 32767.0);

            byte[] peaks = new byte[NUM_FREQUENCY];
            // update meter
            int centerFreq = (waveFormat.SamplesPerSec / 2);
            for (int i = 0; i < NUM_FREQUENCY; ++i)
            {
                byte peak;
                if (METER_FREQUENCY[i] > centerFreq)
                    peak = 0;
                else
                {
                    int index = (int)(METER_FREQUENCY[i] * result.Length / waveFormat.SamplesPerSec);
                    peak = (byte)Math.Max(0, (17.0 * Math.Log10(result.AmplitudeOut[index] / maxAmpl)));
                }

                peaks[i] = peak;
            }

            return peaks;
        }
    }
}
